package authentication;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;

import DAL.*;
import encryption.Hash;
import encryption.RSA;
import entities.*;
import network.Operations;
import network.Server;
import network.ServerConnection;

public class ServerAuthentication {
	private ServerConnection connection;
	public ServerAuthentication(ServerConnection conn){
		connection = conn;
	}

	public boolean authenticate (String email){ //throws NoSuchAlgorithmException, UnsupportedEncodingException, IOException{
		User u = new User();
		u.setEmail(email);
		User[] thisUser = (new UserDA()).selectUsers(u);
		int id = -1;
		if(thisUser.length ==1)id = thisUser[0].getUserID();
		
		String salt;
		try{
			if(id==-1){
				salt = "00000000000=";
				String random = Hash.byteToBase64(Hash.getSalt(8));
				connection.sendMessage(Operations.LOGIN_FAILED+ "");
				//connection.receiveMessage();
				return false;
			}
			else
			{
				UserPass up = new UserPass();
				up.setUserID(id);
				UserPass thisUserPass = (new UserPassDA()).selectUserPasses(up)[0];
				salt = thisUserPass.getSalt();
				System.out.println("From Server, salt "+salt);
				String random = Hash.byteToBase64(Hash.getSalt(8));
				connection.sendMessage("SHA-1 SHA-1 "+salt+" "+random);
				
				String receivedMessageEncrypted = new String(connection.receiveRSAMessage() , "ISO-8859-1");
				String recievedMessage = new RSA().rsadecrypt(receivedMessageEncrypted, Server.privateKeyMod, Server.privateKetExp);
				String [] clientReply = recievedMessage.split(" ");
				
				String randomReply;
				String hashedPass;
				
				if(clientReply.length==3){
					randomReply = clientReply[0];
					hashedPass = clientReply[1];
				}
				else{
					connection.sendMessage(Operations.LOGIN_FAILED+ "");
					return false;
				}
				
				String saltedPass = thisUserPass.getPasswordHash();
				String hashedFromDB = Hash.getFastHashSalt(saltedPass, Hash.base64ToByte(random), "SHA-1");
				if(random.equals(randomReply) && hashedFromDB.equals(hashedPass)){

					connection.sendMessage(Operations.LOGIN_COMPLETE+ "");

					connection.setRandomPassword(clientReply[2]);
					return true;
				}
				else{
					connection.sendMessage(Operations.LOGIN_FAILED+ "");
					return false;
				}
			}
		}
		catch (Exception e){return false;}
	}


	public boolean authenticateAdmin (String email) throws NoSuchAlgorithmException, UnsupportedEncodingException, IOException{
		Admin u = new Admin();
		u.setEmail(email);
		Admin[] thisUser = (new AdminDA()).selectAdmins(u);
		int id = -1;
		if(thisUser.length ==1)
			id = thisUser[0].getAdminID();
		String salt;
		if(id==-1){
			salt = "00000000000=";
			String random = Hash.byteToBase64(Hash.getSalt(8));
			connection.sendMessage(Operations.ADMIN_LOGIN_FAILED+ "");
			
			//connection.receiveMessage();
			return false;
		}
		else
		{
			AdminPass up = new AdminPass();
			up.setAdminID(id);
			AdminPass thisUserPass = (new AdminPassDA()).selectAdminPasses(up)[0];
			salt = thisUserPass.getSalt();
			String random = Hash.byteToBase64(Hash.getSalt(8));
			connection.sendMessage("SHA-1 SHA-1 "+salt+" "+random);
			
			String receivedMessageEncrypted = new String(connection.receiveRSAMessage() , "ISO-8859-1");
			String recievedMessage = new RSA().rsadecrypt(receivedMessageEncrypted, Server.privateKeyMod, Server.privateKetExp);

			
			String [] clientReply = recievedMessage.split(" ");
			String randomReply;
			String hashedPass;
			if(clientReply.length==3){
				randomReply = clientReply[0];
				hashedPass = clientReply[1];
			}
			else{
				connection.sendMessage(Operations.ADMIN_LOGIN_FAILED+ "");
				return false;
			}
			String saltedPass = thisUserPass.getPasswordHash();
			String hashedFromDB = Hash.getFastHashSalt(saltedPass, Hash.base64ToByte(random), "SHA-1");
			if(random.equals(randomReply) && hashedFromDB.equals(hashedPass)){
				connection.sendMessage(Operations.ADMIN_LOGIN_COMPLETE+ "");
				connection.setRandomPassword(clientReply[2]);
				return true;
			}
			else{
				connection.sendMessage(Operations.ADMIN_LOGIN_FAILED+ "");
				return false;
			}
		}
	}

	public void getUserID(String email){
		User u = new User();
		u.setEmail(email);
		User thisUser = (new UserDA()).selectUsers(u)[0];
		int id = thisUser.getUserID();
		connection.setUser(thisUser);
		connection.sendMessage(Operations.GET_ID +" "+id);
	}

	public void getAdminID(String email){
		Admin u = new Admin();
		u.setEmail(email);
		Admin thisUser = (new AdminDA()).selectAdmins(u)[0];
		int id = thisUser.getAdminID();
		connection.setAdmin(thisUser);
		connection.sendMessage(Operations.GET_ID +" "+id);
	}

}
